import Color from "@/utils/Color"
import { lineTo, moveTo, fillRect, fillText, strokeRect, clearRect } from "@/utils/common"

/* canvas的配置 */
// 绘制矩型的高度
let rectHei = 25
// 绘制值的宽度
let rectWit = 14
// 两个矩形横轴相距的距离
let distx = 10
// 两个矩形纵轴相距的距离
let disty = 70
// 最后一层开始绘制的坐标
let start = 10
// canvas宽度


function drawRect(ctx, x, y, width, height) {
  ctx.beginPath()
  ctx.fillStyle = '#F1FFEF'
  fillRect(ctx, x, y, width, height)
  ctx.strokeStyle = 'green'
  strokeRect(ctx, x, y, width, height);
}

function drawText(ctx, x, y, width, height, value) {
  ctx.beginPath()
  let fontSize = 14 * window.devicePixelRatio + 'px'
  ctx.font = fontSize + ' bold serif';
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  ctx.fillStyle = '#438732'
  fillText(ctx, value + '', x + width / 2, y + height / 2)
}

// sx, sy 开始的横纵坐标
// ex, ey 结束的横纵坐标
function drawLine(ctx, sx, sy, ex, ey) {
  moveTo(ctx, sx, sy)
  lineTo(ctx, ex, ey)
  ctx.strokeStyle = 'green'
  ctx.stroke();
}

function getX(xs, order) {
  let leftx = 0
  let rightx = 0
  for (let i = 0; i < order; i++) {
    if (i === 0) {
      leftx = xs.shift().sx
    } else if (i === order - 1) {
      rightx = xs.shift().ex
    } else {
      xs.shift()
    }
  }
  return (leftx + rightx) / 2
}

function getLineXY(lineXYs, sx, sy) {
  let lineXY = lineXYs.shift()
  return {
    sx,
    sy,
    ex: (lineXY.sx + lineXY.ex) / 2,
    ey: lineXY.sy
  }
}


function calculateWidth(datas) {
  let resWid = 0
  datas.forEach(data => {
    resWid += (data + '').length * rectWit

  })
  return resWid
}


function getDistanceToRight(datas) {
  let lastLayer = datas[datas.length - 1]
  let x = start

  for (let i = 0; i < lastLayer.length; i++) {
    let data = lastLayer[i]
    let endx = x
    let width = rectWit * (data + '').replaceAll(',', '').length
    endx += width
    x = distx + endx
  }

  return (document.getElementById('canvas-container2').clientWidth / 2 - 50) - (start + x - distx) / 2

}

export function clear(ctx) {
  let container = document.getElementById('canvas-container2')
  clearRect(ctx, 0, 0, container.clientWidth, container.clientHeight)
}

function rbTreeTo2_3_4_tree(cur, datas, key) {

  if (!cur) {
    return datas
  }


  if (cur.arc.color === Color.BLACK) {
    let values = [cur.value]

    if (cur.left && cur.left.arc.color === Color.RED) {
      values.unshift(cur.left.value)
    }

    if (cur.right && cur.right.arc.color === Color.RED) {
      values.push(cur.right.value)
    }

    if (datas[key]) {
      datas[key].push(values)
    } else {
      datas[key] = [values]
    }

  }

  key = cur.arc.color === Color.BLACK ? key + 1 : key

  rbTreeTo2_3_4_tree(cur.left, datas, key)
  rbTreeTo2_3_4_tree(cur.right, datas, key)
  return datas
}

export default function drawRects(root, ctx) {
  clear(ctx)
  if (!root) return
  let datas = rbTreeTo2_3_4_tree(root, [], 0)

  let shiftRight = getDistanceToRight(datas)

  let y = datas.length * disty
  // xs 记录每层x轴的坐标
  let xs = []
  let linexy = []
  for (let i = datas.length - 1; i >= 0; i--) { // 层
    let x = start + shiftRight
    for (let j = 0; j < datas[i].length; j++) { // 节点
      // [[[], [], [], []], ]
      let data = datas[i][j]


      if (i !== datas.length - 1) {
        x = getX(xs, data.length + 1) - calculateWidth(data) / 2
        // 开始的x坐标
        let { sx, sy, ex, ey } = getLineXY(linexy, x, y + rectHei / 2)
        drawLine(ctx, sx, sy, ex, ey)
      }

      drawRect(ctx, x, y, calculateWidth(data), rectHei)
      let endx = x
      for (let k = 0; k < data.length; k++) { // 值
        let width = rectWit * (data[k] + '').length
        drawText(ctx, endx, y, width, rectHei, data[k])
        endx += width

        if (i !== datas.length - 1) {
          let { sx, sy, ex, ey } = getLineXY(linexy, endx, y + rectHei / 2)
          drawLine(ctx, sx, sy, ex, ey)
        }
      }
      xs.push({ sx: x, ex: endx })
      linexy.push({ sx: x, ex: endx, sy: y })
      x = distx + endx

    }
    y -= disty
  }
}